const util = require( "./util");

module.exports = {

    /**
     * 更具条件获取记录数
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} filter 查询参数 {Object}
     */
    async selectCount(context,tableName,filter) {
        console.info("selectCount:");
        console.info("tableName",tableName);
        console.info("filter",filter);
        const count = await context.cloud.db.collection(tableName).count(
            filter
        );
        console.info("selectCount is complete. result=" + count);
        return count;
    },

    /**
     * 获取单条数据
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} filter 查询参数 {Object}
     */
    async selectOne(context,tableName,filter) {
        console.info("selectOne:");
        console.info("tableName",tableName);
        console.info("filter",filter);
        const result = await context.cloud.db.collection(tableName).find(
            filter,
            {
                limit:1
            }
        );
        console.info("selectOne is complete. result=" + result);
        return result.length>0 ? result[0]:null;
    },

    /**
     * 根据条件获取单条数据, 支持排序等
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} filter 查询参数 {Object}
     * @param {*} options 排序 ....
     */
    async selectOne(context,tableName,filter,options) {
        console.info("selectOne:");
        console.info("tableName",tableName);
        console.info("filter",filter);
        const result = await context.cloud.db.collection(tableName).find(
            filter,
            options
        );
        console.info("selectOne is complete. result=" + result);
        return result.length>0 ? result[0]:null;
    },

    /**
     * 按条件分页查询
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} filter 过滤参数 {Object}
     * @param {*} option 排序,分页等 {Object}
     */
    async selectListPage(context,tableName,pageParam,filter,options) {
        console.info("selectListPage:");
        console.info("tableName",tableName);
        console.info("pageParam",pageParam);
        console.info("filter",filter);
        console.info("options",options);
        let currpage = pageParam.currpage;
        let count = pageParam.count;
        if (currpage < 1 || count < 1) {
            return {
                code:1,
                msg:'分页参数 currpage 或 count 不能小于 1'
            }
        }
        // 获取总记录数
        const totalCount = await this.selectCount(context,tableName,filter);
        if (totalCount <= 0) {
            return {
                code:1,
                msg:'没有数据',
                total_count: totalCount,
                page_total_num: 0,
                currpage: currpage,
                count: count
            };
        }
        
        // 计算总页数 (总记录数 / 每页记录数)
        let pageTotalNum;// 总页数
        if ((totalCount % count) == 0) {
            pageTotalNum = totalCount / count;
        }else {
            pageTotalNum = Number((totalCount / count).toString().split(".")[0]) + 1;
        }

        if (currpage > pageTotalNum) {
            return {
                code:1,
                msg:'页码不合法',
                currpage:currpage,
                page_total_num:pageTotalNum
            }
        }

        // 获取数据
        const data = await context.cloud.db.collection(tableName).find(
            filter,
            options
        );

        return {
            code: 0,
            data: data,
            total_count: totalCount,
            page_total_num: pageTotalNum,
            count: count,
            currpage: currpage
        };
    },

    /**
     * 根据条件查询数据
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} param 查询参数 {Object}
     * @param {*} filter 过滤参数 {Object}
     */
    async selectListAll(context,tableName,filter,option) {
        console.info("selectList:");
        console.info("tableName",tableName);
        console.info("filter",filter);
        console.info("option",option);
        const result = await context.cloud.db.collection(tableName).find(
            filter,
            option
        );
        console.info("selectListAll is complete. result.length=" + result.length);
        return result;
    },

    /**
     * 插入单条数据
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} data 插入参数 {Object}
     * @returns 新增数据的_id
     */
    async insertOne(context,tableName,data) {
        console.info("insertOne:");
        console.info("tableName",tableName);
        console.info("data",JSON.stringify(data));
        const result = await context.cloud.db.collection(tableName).insertOne(
            data
        );
        console.info("insertOne is complete. result=" + result);
        return result;
    },

    /**
     * 根据_id修改数据
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} data 修改的参数 {Object} _id 必传
     */
    async updateById(context,tableName,data,param) {
        console.info("updateById:");
        console.info("tableName",tableName);
        console.info("data:",JSON.stringify(data));
        console.info("param:",JSON.stringify(param));
        if (!data._id) {
            return {
                code:-1,
                meg:'_id-是必须的'
            }
        }
        const result = await context.cloud.db.collection(tableName).updateMany(
            {_id:data._id},
            {$set:param}
        );
        console.info("updateById is complete. result=" + result);
        return result;
    },

    /**
     * 根据任意参数修改数据
     * @param {*} context 
     * @param {*} tableName 
     * @param {*} data 
     * @param {*} param 
     */
    async update(context,tableName,filter,param) {
        console.info("update:");
        console.info("tableName",tableName);
        console.info("filter:",JSON.stringify(filter));
        console.info("param:",JSON.stringify(param));
        const result = await context.cloud.db.collection(tableName).updateMany(
            filter,
            {$set:param}
        );
        console.info("update is complete. result=" + result);
        return result;
    },

    /**
     * 根据 _id 新增或修改单条记录
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} param 参数
     */
    async insertOrUpdate(context,tableName,object,param){
        console.info("insertOrUpdate:");
        console.info("tableName",tableName);
        console.info("data",JSON.stringify(object));
        if (!object) {// insert
            param.create_time = await util.getNowTime();
            param.update_time = await util.getNowTime();
            let res = await this.insertOne(context,tableName,param);
            return {
                code:0,
                status:0,
                msg:'添加成功',
                data: {_id:res}
            }
        }else {// update
            param.update_time = await util.getNowTime();
            let result = await this.update(context,tableName,{_id:object._id},param);
            if (result >= 1) {
                return{
                    code:0,
                    status:0,
                    msg:'修改成功',
                    data:result
                }
            }else {
                return{
                    code:1,
                    status:0,
                    msg: '修改失败',
                    data:result
                }
            }
        }
    },

    /**
     * 根据参数删除
     * @param {*} context 默认请求参数上下文
     * @param {*} tableName 表名
     * @param {*} param 参数 {Object} 多余的条件不能传, '' 不能传入
     */
    async deleteOne(context,tableName,param){
        console.info("deleteOne:")
        console.info("tableName",tableName);
        console.info("param",JSON.stringify(param));
        const result = await context.cloud.db.collection(tableName).deleteMany(param);
        console.info("deleteOne is complete. result=" + result);
        return result;
    },
    /**
     * 聚合查询
     * @param {*} context 
     * @param {*} tableName 表名
     * @param {*} param 参数 {Object} 多余的条件不能传, '' 不能传入
     */
    async aggregate(context,tableName,pipeline){
        console.info("aggregate:")
        console.info("tableName",tableName);
        console.info("param",JSON.stringify(pipeline));
        const result = await context.cloud.db.collection(tableName).aggregate(pipeline);
        console.info("deleteOne is complete. result=" + result);
        return result;
    },
 /**
  * 查询列表
  * @param {*} context 
  * @param {*} tableName 
  * @param {*} filter 
  * @param {*} options 
  * filter	object	是	-	过滤条件
  * options.projection	object	否	-	查询后过滤的字段
  * options.sort	object	否	-	排序规则, key是field名字，value是1或-1
  * options.skip	number	否	-	跳过的文档数量
  * options.limit	number	否	-	查询的文档数量限
  * @result  返回列表
  */
 async find(context,tableName,filter,options){
    console.info("find:")
    console.info("tableName",tableName);
    console.info("filter",filter);
    const cloud = context.cloud; 
    const result = await cloud.db.collection(tableName).find(
        filter, 
        options
    );
    console.info("find done,result.length:",result.length);
    return result;
 },
 /**
  * 分页查询
  * @param {*} context 
  * @param {*} tableName 表名
  * @param {*} filter 过滤条件
  * @param {*} sort 排序条件（1为升序排列，而-1是用于降序排列）
  * @param {*} pageNum 当前页数 （默认1）
  * @param {*} pageSize 每页返回多少条数据 （默认10条）
  */
 async findPage(context,tableName,filter,sort,pageNum,pageSize){
    const cloud = context.cloud; 
    console.info("findPage:")
    console.info("tableName",tableName);
    console.info("filter",filter);
    console.info("sort",sort);
    if(!pageNum){
       pageNum=1;
    }
    if(!pageSize){
       pageSize=10;
    }
    //跳过多少条记录
    const skip = ((pageNum-1)*pageSize);
    //限制返回数量
    const limit = pageSize;
    //总记录数
    let total = await this.count(context,tableName,filter);
    //总页数(向上取整)
    let pageCount = Math.ceil(total/pageSize);
    const options = {sort,skip,limit};
    
    //返回当前集合
    let list = await this.find(context,tableName,filter,options);
    result={
       list,total,pageCount,pageSize,
    };
    console.info("find done,total:",total);
    return result;
 },
 /**
  * 查询所有
  * @param {*} context 
  * @param {*} tableName 表名
  * @param {*} filter 过滤条件
  * @param {*} sort 排序条件（1为升序排列，而-1是用于降序排列）
  */
 async findAll(context,tableName,filter,sort){
    console.info("findAll:")
    console.info("tableName",tableName);
    console.info("filter",filter);
    console.info("sort",sort);
    let result = [];
    let pageSize = 500;
    let page = await this.findPage(context,tableName,filter,sort,1,pageSize);
    let pageCount = page.pageCount;

    for(let pageNum=1;pageNum<=pageCount;pageNum++){
      // console.info("pageNum<=pageCount",pageNum<=pageCount)
      // console.info("当前页数:"+pageNum+"总页数:"+pageCount)
       page = await this.findPage(context,tableName,filter,sort,pageNum,pageSize);
       let list = page.list;
       if(list.length==0){
          break;
       }
       for(let item of list){
          result.push(item);
       }
    }
    return result;
 },
  /**
  * 获取集合中复合条件的记录数量
  * @param {*} context 
  * @param {*} filter 
  * @result  数据数量
  */
 async count(context,tableName,filter){
    console.info("count:")
    console.info("tableName",tableName);
    console.info("filter",filter);
    const cloud = context.cloud; 
    const result = await cloud.db.collection(tableName).count(filter);
    console.info("count done,result:",result)
    return result;
 },
}